package com.example.routeplansystem.controller;

import java.io.IOException;
import java.io.InputStream;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.PageReadListener;
import com.example.routeplansystem.anotation.UserPermissionConf;
import com.example.routeplansystem.entity.bo.SolutionExcelBO;
import com.example.routeplansystem.entity.dto.ResponseEntity;
import com.example.routeplansystem.entity.po.FinalSolution;
import com.example.routeplansystem.entity.po.NodePojo;
import com.example.routeplansystem.entity.vo.FinalSolutionRes;
import com.example.routeplansystem.service.impl.FinalSolutionServiceImp;
import com.example.routeplansystem.utils.ExcelUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author lucong
 * @Date 2022/4/15
 * @Description
 */
@RestController
@RequestMapping("scheme")
@Api(tags = "计算方案")
@Validated
@Slf4j
@UserPermissionConf
public class FinalSolutionController {

    @Autowired
    private FinalSolutionServiceImp finalSolutionService;


    @GetMapping("/list")
    @ApiOperation("获得一个问题的所有方案")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionId", paramType = "query", value = "问题Id", required = true)
    })
    public ResponseEntity<List<FinalSolutionRes>> listFinalSolution(@NotNull(message = "问题Id不能为空") @RequestParam("questionId") int questionId) throws ServerException {
        List<FinalSolutionRes> list = finalSolutionService.listFinalSolution(questionId);
        return new ResponseEntity<>(list);
    }

    @GetMapping("{finalSolutionId}")
    @ApiOperation("根据方案Id获得方案")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "FinalSolutionId", paramType = "path", value = "方案Id", required = true)
    })
    public ResponseEntity<FinalSolutionRes> getFinalSolution(@NotNull(message = "方案Id") @PathVariable("finalSolutionId") Integer finalSolutionId) throws ServerException {
        FinalSolutionRes res = finalSolutionService.getFinalSolution(finalSolutionId);
        return new ResponseEntity<>(res);
    }

    @GetMapping("nodes/{finalSolutionId}")
    @ApiOperation("根据方案Id获得经过的点供渲染")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "FinalSolutionId", paramType = "path", value = "方案Id", required = true)
    })
    public ResponseEntity<List<NodePojo>> getNodesByScheme(@NotNull(message = "方案Id") @PathVariable("finalSolutionId") Integer finalSolutionId) throws ServerException {
        List<NodePojo> res = finalSolutionService.getNodes(finalSolutionId);
        return new ResponseEntity<>(res);
    }

    @PostMapping
    @ApiOperation("计算较优路径")
    public ResponseEntity<Integer> addSolution(@NotNull(message = "算法key值不能为空") @RequestParam("key") Integer key,
                                               @NotNull(message = "问题Id不能为空") @RequestParam("questionId") Integer questionId) throws ServerException {
        FinalSolution fs = finalSolutionService.insertFinalSolution(key, questionId);
        Integer FinalSolutionId = finalSolutionService.addSolution(key, questionId, fs);
        return new ResponseEntity<>(FinalSolutionId);
    }


    @PostMapping("import/{questionId}")
    @ApiOperation("导入配送方案")
    public ResponseEntity<Integer> importFinalSolution(@RequestAttribute(value = "userId", required = false) Integer userId,
                                                       @NotNull(message = "问题Id不能为空") @PathVariable("questionId") Integer questionId,
                                                       @RequestBody MultipartFile file) {
        ExcelUtil.checkFile(file);
        List<SolutionExcelBO> list = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream()) {
            EasyExcel.read(inputStream, SolutionExcelBO.class, new PageReadListener<SolutionExcelBO>(dataList -> {
                list.addAll(dataList);
            })).sheet().doRead();
        } catch (ExcelCommonException e) {
            throw new RuntimeException("只允许上传Excel文件");
        } catch (ExcelDataConvertException e) {
            throw new RuntimeException("文件内容格式错误，请确认路线编号，客户ID，顺序必须为整数");
        } catch (IOException e) {
            e.printStackTrace();
        }
        Integer finalSolutionId = finalSolutionService.importFinalSolution(-1, userId, questionId, list);
        return new ResponseEntity<>(finalSolutionId);
    }


    @GetMapping("downloadResult")
    @ApiOperation("获取某个方案的路线")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "finalSolutionId", value = "问题Id", paramType = "query"),
    })
    @Validated
    public ResponseEntity<String> downloadQuestionNodes(HttpServletRequest request, HttpServletResponse response, @NotNull(message = "finalSolutionId 不能为空") @RequestParam("finalSolutionId") Integer finalSolutionId) {

        return finalSolutionService.resultExport(request, response, finalSolutionId);
    }

    @GetMapping("getFinalSolutionStatus")
    @ApiOperation("获取方案的状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "finalSolutionId", value = "方案Id", paramType = "int"),
    })
    public ResponseEntity<Integer> getFinalSolutionStatus(@NotNull(message = "方案Id不能为空") @RequestParam("finalSolutionId") Integer finalSolutionId) {
        return finalSolutionService.getFinalSolutionStatus(finalSolutionId);
    }

}
